package com.hlj.ncp.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hlj.ncp.common.core.domain.AjaxResult;
import com.hlj.ncp.system.entity.SysRole;
import com.hlj.ncp.system.entity.SysRoleMenu;
import com.hlj.ncp.system.mapper.SysRoleMapper;
import com.hlj.ncp.system.mapper.SysRoleMenuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 角色信息
 */
@Controller
@RequestMapping("/system/role")
public class RoleController {
    
    @Autowired
    private SysRoleMapper roleMapper;
    
    @Autowired
    private SysRoleMenuMapper roleMenuMapper;
    
    /**
     * 角色管理页面
     */
    @GetMapping({"", "/", "/index"})
    public String index() {
        return "system/role/index";
    }
    
    /**
     * 获取角色列表
     */
    @PostMapping("/list")
    @ResponseBody
    @Cacheable(value = "roleList", key = "#params.toString()", unless = "#result.get('code') != 200")
    @Transactional(readOnly = true)
    public AjaxResult list(@RequestBody Map<String, Object> params) {
        Integer pageNum = (Integer) params.getOrDefault("pageNum", 1);
        Integer pageSize = (Integer) params.getOrDefault("pageSize", 10);
        String roleName = (String) params.get("roleName");
        String roleKey = (String) params.get("roleKey");
        String status = (String) params.get("status");
        
        // 构建查询条件
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getDelFlag, "0");
        
        if (StringUtils.hasText(roleName)) {
            queryWrapper.like(SysRole::getRoleName, roleName);
        }
        if (StringUtils.hasText(roleKey)) {
            queryWrapper.like(SysRole::getRoleKey, roleKey);
        }
        if (StringUtils.hasText(status)) {
            queryWrapper.eq(SysRole::getStatus, status);
        }
        
        // 排序
        queryWrapper.orderByAsc(SysRole::getRoleSort);
        
        // 分页查询
        Page<SysRole> page = new Page<>(pageNum, pageSize);
        Page<SysRole> rolePage = roleMapper.selectPage(page, queryWrapper);
        
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("total", rolePage.getTotal());
        result.put("rows", rolePage.getRecords());
        
        return AjaxResult.success(result);
    }
    
    /**
     * 获取角色选择框列表
     */
    @GetMapping("/optionselect")
    @ResponseBody
    public AjaxResult optionselect() {
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getDelFlag, "0");
        queryWrapper.eq(SysRole::getStatus, "0"); // 只查询正常状态的角色
        List<SysRole> roles = roleMapper.selectList(queryWrapper);
        return AjaxResult.success(roles);
    }
    
    /**
     * 新增角色
     */
    @PostMapping("/add")
    @ResponseBody
    @CacheEvict(value = "roleList", allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody SysRole role) {
        // 验证角色名称和权限字符是否已存在
        if (checkRoleNameUnique(role) != 0) {
            return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败，角色名称已存在");
        }
        if (checkRoleKeyUnique(role) != 0) {
            return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        
        // 设置默认值
        role.setDelFlag("0");
        role.setCreateTime(LocalDateTime.now());
        role.setCreateBy(getCurrentUsername());
        
        // 插入数据
        int rows = roleMapper.insert(role);
        
        // 保存角色菜单关系
        insertRoleMenu(role);
        
        return rows > 0 ? AjaxResult.success() : AjaxResult.error("新增角色失败");
    }
    
    /**
     * 修改角色
     */
    @PostMapping("/update")
    @ResponseBody
    @CacheEvict(value = "roleList", allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult update(@RequestBody SysRole role) {
        // 验证角色是否存在
        SysRole existRole = roleMapper.selectById(role.getRoleId());
        if (existRole == null) {
            return AjaxResult.error("角色不存在");
        }
        
        // 验证角色名称和权限字符是否已存在
        if (!existRole.getRoleName().equals(role.getRoleName()) && checkRoleNameUnique(role) != 0) {
            return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败，角色名称已存在");
        }
        if (!existRole.getRoleKey().equals(role.getRoleKey()) && checkRoleKeyUnique(role) != 0) {
            return AjaxResult.error("修改角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        
        // 设置更新信息
        role.setUpdateTime(LocalDateTime.now());
        role.setUpdateBy(getCurrentUsername());
        
        // 更新数据
        int rows = roleMapper.updateById(role);
        
        // 更新角色菜单关系
        roleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId());
        insertRoleMenu(role);
        
        return rows > 0 ? AjaxResult.success() : AjaxResult.error("修改角色失败");
    }
    
    /**
     * 删除角色
     */
    @PostMapping("/delete")
    @ResponseBody
    @CacheEvict(value = "roleList", allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult delete(@RequestBody Map<String, Object> params) {
        Long roleId = Long.valueOf(params.get("roleId").toString());
        
        // 验证角色是否存在
        SysRole role = roleMapper.selectById(roleId);
        if (role == null) {
            return AjaxResult.error("角色不存在");
        }
        
        // 逻辑删除
        role.setDelFlag("1");
        role.setUpdateTime(LocalDateTime.now());
        role.setUpdateBy(getCurrentUsername());
        
        int rows = roleMapper.updateById(role);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error("删除角色失败");
    }
    
    /**
     * 获取角色详细信息
     */
    @GetMapping("/{roleId}")
    @ResponseBody
    public AjaxResult getInfo(@PathVariable Long roleId) {
        return AjaxResult.success(roleMapper.selectById(roleId));
    }
    
    /**
     * 获取角色菜单列表
     */
    @GetMapping("/roleMenuList/{roleId}")
    @ResponseBody
    public AjaxResult roleMenuList(@PathVariable("roleId") Long roleId) {
        LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRoleMenu::getRoleId, roleId);
        List<SysRoleMenu> list = roleMenuMapper.selectList(queryWrapper);
        
        List<Long> menuIds = new ArrayList<>();
        for (SysRoleMenu rm : list) {
            menuIds.add(rm.getMenuId());
        }
        
        return AjaxResult.success(menuIds);
    }
    
    /**
     * 检查角色名称是否唯一
     */
    private int checkRoleNameUnique(SysRole role) {
        Long roleId = role.getRoleId() == null ? -1L : role.getRoleId();
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleName, role.getRoleName());
        queryWrapper.eq(SysRole::getDelFlag, "0");
        queryWrapper.ne(roleId > 0, SysRole::getRoleId, roleId);
        return roleMapper.selectCount(queryWrapper).intValue();
    }
    
    /**
     * 检查角色权限是否唯一
     */
    private int checkRoleKeyUnique(SysRole role) {
        Long roleId = role.getRoleId() == null ? -1L : role.getRoleId();
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleKey, role.getRoleKey());
        queryWrapper.eq(SysRole::getDelFlag, "0");
        queryWrapper.ne(roleId > 0, SysRole::getRoleId, roleId);
        return roleMapper.selectCount(queryWrapper).intValue();
    }
    
    /**
     * 新增角色菜单信息
     */
    private void insertRoleMenu(SysRole role) {
        // 获取前端传过来的菜单ID集合
        Long[] menuIds = role.getMenuIds();
        if (menuIds != null && menuIds.length > 0) {
            // 批量添加角色菜单关联信息
            List<SysRoleMenu> list = new ArrayList<>();
            for (Long menuId : menuIds) {
                SysRoleMenu rm = new SysRoleMenu();
                rm.setRoleId(role.getRoleId());
                rm.setMenuId(menuId);
                list.add(rm);
            }
            if (!list.isEmpty()) {
                roleMenuMapper.batchRoleMenu(list);
            }
        }
    }
    
    /**
     * 获取当前登录用户名
     */
    private String getCurrentUsername() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return authentication.getName();
    }
} 